<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.3.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/yuwanzi.io/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/yuwanzi.io/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/yuwanzi.io/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/yuwanzi.io/images/logo.svg" color="#222">

<link rel="stylesheet" href="/yuwanzi.io/css/main.css">



<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.1/css/all.min.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css">

<script class="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"suyuhuan.gitee.io","root":"/yuwanzi.io/","images":"/yuwanzi.io/images","scheme":"Muse","version":"8.2.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":false,"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"Suche...","empty":"We didn't find any results for the search: ${query}","hits_time":"${hits} results found in ${time} ms","hits":"${hits} results found"}};
  </script>
<meta name="description" content="SSL安全套接层 概述 &amp;nbsp;&amp;nbsp;SSL(Secure Sockets Layer)是专门用于网络通信安全及数据完整性的安全协议,它会在网络传输层对网络连接进行加密. &amp;nbsp;&amp;nbsp;SSL协议是位于TCP&#x2F;IP协议与其他各种应用层协议之间的. &amp;nbsp;&amp;nbsp;SSL的体系结构中包含两个协议子层:  SSL记录协议(SSL Record Protocol),它建立在可">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring Boot消息通信">
<meta property="og:url" content="https://suyuhuan.gitee.io/yuwanzi.io/2016/08/03/2016-08-3-Spring-message/index.html">
<meta property="og:site_name" content="玉丸子 | Blog">
<meta property="og:description" content="SSL安全套接层 概述 &amp;nbsp;&amp;nbsp;SSL(Secure Sockets Layer)是专门用于网络通信安全及数据完整性的安全协议,它会在网络传输层对网络连接进行加密. &amp;nbsp;&amp;nbsp;SSL协议是位于TCP&#x2F;IP协议与其他各种应用层协议之间的. &amp;nbsp;&amp;nbsp;SSL的体系结构中包含两个协议子层:  SSL记录协议(SSL Record Protocol),它建立在可">
<meta property="og:locale">
<meta property="og:image" content="http://ww2.sinaimg.cn/mw690/63503acbjw1f6mihqw3jpj20sg0dttc2.jpg">
<meta property="og:image" content="http://ww1.sinaimg.cn/mw690/63503acbjw1f6mihr9qtsj20om0ddadp.jpg">
<meta property="article:published_time" content="2016-08-03T10:00:00.000Z">
<meta property="article:modified_time" content="2020-11-07T00:58:17.000Z">
<meta property="article:author" content="玉丸子">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Spring">
<meta property="article:tag" content="Spring Boot">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://ww2.sinaimg.cn/mw690/63503acbjw1f6mihqw3jpj20sg0dttc2.jpg">


<link rel="canonical" href="https://suyuhuan.gitee.io/yuwanzi.io/2016/08/03/2016-08-3-Spring-message/">


<script class="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh'
  };
</script>
<title>Spring Boot消息通信 | 玉丸子 | Blog</title>
  




  <noscript>
  <style>
  body { margin-top: 2rem; }

  .use-motion .menu-item,
  .use-motion .sidebar,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header {
    visibility: visible;
  }

  .use-motion .header,
  .use-motion .site-brand-container .toggle,
  .use-motion .footer { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle,
  .use-motion .custom-logo-image {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line {
    transform: scaleX(1);
  }

  .search-pop-overlay, .sidebar-nav { display: none; }
  .sidebar-panel { display: block; }
  </style>
</noscript>

<link rel="alternate" href="/yuwanzi.io/atom.xml" title="玉丸子 | Blog" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Navigationsleiste an/ausschalten" role="button">
    </div>
  </div>

  <div class="site-meta">

    <a href="/yuwanzi.io/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">玉丸子 | Blog</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>







</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          Inhaltsverzeichnis
        </li>
        <li class="sidebar-nav-overview">
          Übersicht
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#SSL%E5%AE%89%E5%85%A8%E5%A5%97%E6%8E%A5%E5%B1%82"><span class="nav-number">1.</span> <span class="nav-text">SSL安全套接层</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%A6%82%E8%BF%B0"><span class="nav-number">1.1.</span> <span class="nav-text">概述</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B"><span class="nav-number">1.2.</span> <span class="nav-text">工作流程</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Spring-Boot%E4%B8%AD%E9%85%8D%E7%BD%AESSL"><span class="nav-number">1.3.</span> <span class="nav-text">Spring Boot中配置SSL</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E7%94%9F%E6%88%90SSL%E8%AF%81%E4%B9%A6"><span class="nav-number">1.3.1.</span> <span class="nav-text">生成SSL证书</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#%E9%85%8D%E7%BD%AE%E5%88%B0%E9%A1%B9%E7%9B%AE%E4%B8%AD"><span class="nav-number">1.3.2.</span> <span class="nav-text">配置到项目中</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#http%E8%87%AA%E5%8A%A8%E8%BD%AC%E5%90%91https"><span class="nav-number">1.4.</span> <span class="nav-text">http自动转向https</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#WebSocket"><span class="nav-number">2.</span> <span class="nav-text">WebSocket</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%A6%82%E8%BF%B0-1"><span class="nav-number">2.1.</span> <span class="nav-text">概述</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Spring-Boot%E6%94%AF%E6%8C%81"><span class="nav-number">2.2.</span> <span class="nav-text">Spring Boot支持</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Example"><span class="nav-number">2.3.</span> <span class="nav-text">Example</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#%E5%B9%BF%E6%92%AD"><span class="nav-number">2.3.1.</span> <span class="nav-text">广播</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#P2P"><span class="nav-number">2.3.2.</span> <span class="nav-text">P2P</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%BC%82%E6%AD%A5%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97"><span class="nav-number">3.</span> <span class="nav-text">异步消息队列</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Spring-Boot%E6%94%AF%E6%8C%81-1"><span class="nav-number">3.1.</span> <span class="nav-text">Spring Boot支持</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#JMS-Example"><span class="nav-number">3.2.</span> <span class="nav-text">JMS Example</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#AMQP-Example"><span class="nav-number">3.3.</span> <span class="nav-text">AMQP Example</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#end"><span class="nav-number">4.</span> <span class="nav-text">end</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">玉丸子</p>
  <div class="site-description" itemprop="description">这里是玉丸子的个人博客,与你一起发现更大的世界。</div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/yuwanzi.io/archives">
          <span class="site-state-item-count">68</span>
          <span class="site-state-item-name">Artikel</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/yuwanzi.io/categories/">
        <span class="site-state-item-count">39</span>
        <span class="site-state-item-name">Kategorien</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/yuwanzi.io/tags/">
        <span class="site-state-item-count">46</span>
        <span class="site-state-item-name">schlagwörter</span></a>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh">
    <link itemprop="mainEntityOfPage" href="https://suyuhuan.gitee.io/yuwanzi.io/2016/08/03/2016-08-3-Spring-message/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/yuwanzi.io/images/avatar.gif">
      <meta itemprop="name" content="玉丸子">
      <meta itemprop="description" content="这里是玉丸子的个人博客,与你一起发现更大的世界。">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="玉丸子 | Blog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Spring Boot消息通信
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">Veröffentlicht am</span>

      <time title="Erstellt: 2016-08-03 18:00:00" itemprop="dateCreated datePublished" datetime="2016-08-03T18:00:00+08:00">2016-08-03</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">Bearbeitet am</span>
        <time title="Geändert am: 2020-11-07 08:58:17" itemprop="dateModified" datetime="2020-11-07T08:58:17+08:00">2020-11-07</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">in</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/yuwanzi.io/categories/%E5%90%8E%E7%AB%AF/" itemprop="url" rel="index"><span itemprop="name">后端</span></a>
        </span>
          . 
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/yuwanzi.io/categories/%E5%90%8E%E7%AB%AF/Java/" itemprop="url" rel="index"><span itemprop="name">Java</span></a>
        </span>
          . 
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/yuwanzi.io/categories/%E5%90%8E%E7%AB%AF/Java/Spring-Boot/" itemprop="url" rel="index"><span itemprop="name">Spring Boot</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h3 id="SSL安全套接层"><a href="#SSL安全套接层" class="headerlink" title="SSL安全套接层"></a>SSL安全套接层</h3><hr>
<h4 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h4><hr>
<p>&nbsp;&nbsp;SSL(Secure Sockets Layer)是专门用于网络通信安全及数据完整性的安全协议,它会在网络传输层对网络连接进行加密.</p>
<p>&nbsp;&nbsp;SSL协议是位于TCP/IP协议与其他各种应用层协议之间的.</p>
<p>&nbsp;&nbsp;SSL的体系结构中包含两个协议子层:</p>
<ol>
<li><p>SSL记录协议(SSL Record Protocol),它建立在可靠的传输协议(TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持.SSL纪录协议针对HTTP协议进行了特别的设计，使得超文本的传输协议HTTP能够在SSL运行.</p>
</li>
<li><p>SSL握手协议(SSL Handshake Protocol),它建立在SSL记录协议之上.SSL握手协议层包括SSL握手协议（SSL HandShake Protocol）、SSL密码参数修改协议（SSL Change Cipher Spec Protocol）、应用数据协议（Application Data Protocol）和SSL告警协议（SSL Alert Protocol）.它主要用于在实际数据传输开始前,通信双方进行身份认证、协商加密算法、交换加密密钥等.</p>
<p>&nbsp;&nbsp;在B/S应用中,是通过<strong>HTTPS</strong>实现SSL的,<strong>HTTPS</strong>即是在HTTP下加入SSL层,它的安全基础是SSL.</p>
</li>
</ol>
<h4 id="工作流程"><a href="#工作流程" class="headerlink" title="工作流程"></a>工作流程</h4><hr>
<ol>
<li>客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接.</li>
<li>服务器根据客户的信息确定是否需要生成新的主密钥，如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息.</li>
<li>客户根据收到的服务器响应信息，产生一个主密钥，并用服务器的公开密钥加密后传给服务器.</li>
<li>服务器回复该主密钥，并返回给客户一个用主密钥认证的信息，以此让客户认证服务器.</li>
</ol>
<h4 id="Spring-Boot中配置SSL"><a href="#Spring-Boot中配置SSL" class="headerlink" title="Spring Boot中配置SSL"></a>Spring Boot中配置SSL</h4><hr>
<p>&nbsp;&nbsp;在配置SSL之前需要生成一个证书,它可以是自签名的,也可以是从SSL证书授权中心获得的.</p>
<h5 id="生成SSL证书"><a href="#生成SSL证书" class="headerlink" title="生成SSL证书"></a>生成SSL证书</h5><p>&nbsp;&nbsp;可以在控制台中输入以下指令,生成自签名的SSL证书:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">keytool -genkey -alias tomcat</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;之后会在当前目录生成一个.keystore文件,它就是SSL证书文件.</p>
<h5 id="配置到项目中"><a href="#配置到项目中" class="headerlink" title="配置到项目中"></a>配置到项目中</h5><ol>
<li>将.keystore文件复制到src/main/resources/static下.</li>
<li>在application.properties中如下配置:<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">server.port &#x3D; 8090</span><br><span class="line">server.ssl.key-store &#x3D; .keystore</span><br><span class="line">server.ssl.key-store-password &#x3D; 123456</span><br><span class="line">server.ssl.keyStoreType &#x3D; JKS</span><br><span class="line">server.ssl.keyAlias : tomcat</span><br></pre></td></tr></table></figure>
<h4 id="http自动转向https"><a href="#http自动转向https" class="headerlink" title="http自动转向https"></a>http自动转向https</h4></li>
</ol>
<hr>
<p>&nbsp;&nbsp;如果想要实现输入http自动转向到https,则需要配置<strong>TomcatEmbeddedServletContainerFactory</strong>,并添加Tomcat的connector来实现.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.sun.sylvanas.spring_boot_security;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.catalina.Context;</span><br><span class="line"><span class="keyword">import</span> org.apache.catalina.connector.Connector;</span><br><span class="line"><span class="keyword">import</span> org.apache.tomcat.util.descriptor.web.SecurityCollection;</span><br><span class="line"><span class="keyword">import</span> org.apache.tomcat.util.descriptor.web.SecurityConstraint;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.SpringApplication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"></span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringBootSecurityApplication</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SpringApplication.run(SpringBootSecurityApplication.class, args);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Bean</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> EmbeddedServletContainerFactory <span class="title">servletContainerFactory</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		TomcatEmbeddedServletContainerFactory tomcat = <span class="keyword">new</span> TomcatEmbeddedServletContainerFactory()&#123;</span><br><span class="line">			<span class="meta">@Override</span></span><br><span class="line">			<span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">postProcessContext</span><span class="params">(Context context)</span> </span>&#123;</span><br><span class="line">				SecurityConstraint securityConstraint = <span class="keyword">new</span> SecurityConstraint();</span><br><span class="line">				securityConstraint.setUserConstraint(<span class="string">&quot;CONFIDENTIAL&quot;</span>);</span><br><span class="line">				SecurityCollection securityCollection = <span class="keyword">new</span> SecurityCollection();</span><br><span class="line">				securityCollection.addPattern(<span class="string">&quot;/&quot;</span>);</span><br><span class="line">				securityConstraint.addCollection(securityCollection);</span><br><span class="line">				context.addConstraint(securityConstraint);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;;</span><br><span class="line">		tomcat.addAdditionalTomcatConnectors(httpConnector());</span><br><span class="line">		<span class="keyword">return</span> tomcat;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Bean</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> Connector <span class="title">httpConnector</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		Connector connector = <span class="keyword">new</span> Connector(<span class="string">&quot;org.apache.coyote.http11.Http11NioProtocol&quot;</span>);</span><br><span class="line">		connector.setScheme(<span class="string">&quot;http&quot;</span>);</span><br><span class="line">		connector.setPort(<span class="number">8080</span>);</span><br><span class="line">		connector.setSecure(<span class="keyword">false</span>);</span><br><span class="line">		connector.setRedirectPort(<span class="number">8090</span>);</span><br><span class="line">		<span class="keyword">return</span> connector;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;此时访问<a href="http://localhost:8080会自动转向到https://localhost:8090">http://localhost:8080会自动转向到https://localhost:8090</a>.</p>
<h3 id="WebSocket"><a href="#WebSocket" class="headerlink" title="WebSocket"></a>WebSocket</h3><hr>
<h4 id="概述-1"><a href="#概述-1" class="headerlink" title="概述"></a>概述</h4><hr>
<p><img src="http://ww2.sinaimg.cn/mw690/63503acbjw1f6mihqw3jpj20sg0dttc2.jpg"><br>&nbsp;&nbsp;WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工异步通信(full-duplex).即浏览器可以向服务端发送消息,服务端也可以向浏览器发送消息.WebSocket需要浏览器的支持,如IE 10+、Chrome 13+、Firefox 6+.</p>
<p>&nbsp;&nbsp;WebSocket是通过一个socket来实现双工异步通信功能的.直接使用WebSocket协议开发程序会很繁琐,所以一般使用它的子协议<strong>STOMP</strong>,<strong>STOMP</strong>是一个更高级别的协议,它使用基于帧(frame)的格式来定义消息,具有一个类似<code>@RequestMapping</code>的<code>@MessageMapping</code>.</p>
<h4 id="Spring-Boot支持"><a href="#Spring-Boot支持" class="headerlink" title="Spring Boot支持"></a>Spring Boot支持</h4><hr>
<p>&nbsp;&nbsp;Spring Boot对内嵌的Tomcat(7、8)、Jetty9、Undertow提供了WebSocket支持.依赖为spring-boot-starter-websocket.</p>
<p>&nbsp;&nbsp;配置WebSocket需要在配置类上使用<code>@EnableWebSocketMessageBroker</code>注解开启支持,并且继承<strong>AbstractWebSocketMessageBrokerConfigurer</strong>类,重写其方法进行配置.</p>
<h4 id="Example"><a href="#Example" class="headerlink" title="Example"></a>Example</h4><hr>
<h5 id="广播"><a href="#广播" class="headerlink" title="广播"></a>广播</h5><p>&nbsp;&nbsp;广播即服务端有消息时,会将消息发送给所有连接了当前endpoint的浏览器.</p>
<ol>
<li><p>配置</p>
<p><img src="http://ww1.sinaimg.cn/mw690/63503acbjw1f6mihr9qtsj20om0ddadp.jpg"></p>
</li>
<li><p>Controller</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@MessageMapping</span>注解映射/hello这个地址,类似于<span class="doctag">@RequestMapping</span></span></span><br><span class="line"><span class="comment">  * 当服务端有消息时,会对订阅了<span class="doctag">@SendTo</span>中的路径的浏览器发送消息.</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> <span class="meta">@MessageMapping(&quot;/hello&quot;)</span></span><br><span class="line"> <span class="meta">@SendTo(&quot;/topic/getHello&quot;)</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">hello</span><span class="params">(String name)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">     Thread.sleep(<span class="number">3000</span>);</span><br><span class="line">     <span class="keyword">return</span> <span class="string">&quot;Hello &quot;</span> + name + <span class="string">&quot;!&quot;</span>;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>js</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line">  &lt;html xmlns:th=<span class="string">&quot;http://www.thymeleaf.org&quot;</span>&gt;</span><br><span class="line"></span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta content=<span class="string">&quot;text/html;charset=UTF-8&quot;</span>/&gt;</span><br><span class="line">    &lt;meta http-equiv=<span class="string">&quot;X-UA-Compatible&quot;</span> content=<span class="string">&quot;IE=edge&quot;</span>/&gt;</span><br><span class="line">    &lt;meta name=<span class="string">&quot;viewport&quot;</span> content=<span class="string">&quot;width=device-width,initial-scale=1&quot;</span>/&gt;</span><br><span class="line">    &lt;title&gt;Spring Boot+WebSocket+广播式&lt;/title&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body onload=<span class="string">&quot;disconnect()&quot;</span>&gt;</span><br><span class="line">&lt;noscript&gt;<span class="xml"><span class="tag">&lt;<span class="name">h2</span> <span class="attr">style</span>=<span class="string">&quot;color: #ff0000&quot;</span>&gt;</span>貌似你的浏览器不支持websocket<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span>&lt;/noscript&gt;</span><br><span class="line">&lt;div&gt;</span><br><span class="line">    &lt;div&gt;</span><br><span class="line">        &lt;button id=<span class="string">&quot;connect&quot;</span> onclick=<span class="string">&quot;connect();&quot;</span>&gt;连接&lt;/button&gt;</span><br><span class="line">        &lt;button id=<span class="string">&quot;disconnect&quot;</span> onclick=<span class="string">&quot;disconnect();&quot;</span>&gt;断开连接&lt;/button&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">    &lt;div id=<span class="string">&quot;conversationDiv&quot;</span>&gt;</span><br><span class="line">        &lt;label&gt;输入你的名字&lt;<span class="regexp">/label&gt;&lt;input type=&quot;text&quot; id=&quot;name&quot;/</span>&gt;</span><br><span class="line">        &lt;button id=<span class="string">&quot;sendName&quot;</span> onclick=<span class="string">&quot;sendName();&quot;</span>&gt;发送&lt;/button&gt;</span><br><span class="line">        &lt;p id=<span class="string">&quot;response&quot;</span>&gt;&lt;/p&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line">&lt;!-- 导入jQuery --&gt;</span><br><span class="line">&lt;script th:src=<span class="string">&quot;@&#123;jquery-3.1.0.min.js&#125;&quot;</span>/&gt;</span><br><span class="line">&lt;script th:src=<span class="string">&quot;@&#123;sockjs-1.0.0.min.js&#125;&quot;</span>/&gt;</span><br><span class="line">&lt;script th:src=<span class="string">&quot;@&#123;stomp.min.js&#125;&quot;</span>/&gt;</span><br><span class="line">&lt;script type=<span class="string">&quot;text/javascript&quot;</span>&gt;</span><br><span class="line">    <span class="keyword">var</span> stompClient = <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">setConnected</span>(<span class="params">connected</span>) </span>&#123;</span><br><span class="line">        <span class="built_in">document</span>.getElementById(<span class="string">&#x27;connect&#x27;</span>).disabled = connected;</span><br><span class="line">        <span class="built_in">document</span>.getElementById(<span class="string">&#x27;disconnect&#x27;</span>).disabled = !connected;</span><br><span class="line">        <span class="built_in">document</span>.getElementById(<span class="string">&#x27;conversationDiv&#x27;</span>).style.visibility = connected ? <span class="string">&#x27;visible&#x27;</span> : <span class="string">&#x27;hidden&#x27;</span>;</span><br><span class="line">        $(<span class="string">&#x27;#response&#x27;</span>).html();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">connect</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> socket = <span class="keyword">new</span> SockJS(<span class="string">&#x27;/endpointSun&#x27;</span>);</span><br><span class="line">        stompClient = Stomp.over(socket);</span><br><span class="line">        stompClient.connect(&#123;&#125;, <span class="function"><span class="keyword">function</span> (<span class="params">frame</span>) </span>&#123;</span><br><span class="line">            setConnected(<span class="literal">true</span>);</span><br><span class="line">            <span class="built_in">console</span>.log(<span class="string">&#x27;Connected: &#x27;</span> + frame);</span><br><span class="line">            <span class="comment">// 订阅/topic/getHello</span></span><br><span class="line">            stompClient.subscribe(<span class="string">&#x27;/topic/getHello&#x27;</span>,<span class="function"><span class="keyword">function</span>(<span class="params">response</span>)</span>&#123;</span><br><span class="line">                showResponse(<span class="built_in">JSON</span>.parse(response.body).responseMessage);</span><br><span class="line">            &#125;);</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">disconnect</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(stompClient != <span class="literal">null</span>)&#123;</span><br><span class="line">            stompClient.disconnect();</span><br><span class="line">        &#125;</span><br><span class="line">        setConnected(<span class="literal">false</span>);</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&quot;Disconnected&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">sendName</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> name = $(<span class="string">&#x27;#name&#x27;</span>).val();</span><br><span class="line">        <span class="comment">// 发送到/hello</span></span><br><span class="line">        stompClient.send(<span class="string">&quot;/hello&quot;</span>,&#123;&#125;,<span class="built_in">JSON</span>.stringify(&#123;<span class="string">&#x27;name&#x27;</span>:name&#125;));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">showResponse</span>(<span class="params">message</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> response = $(<span class="string">&quot;#response&quot;</span>);</span><br><span class="line">        response.html(message);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line"></span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<h5 id="P2P"><a href="#P2P" class="headerlink" title="P2P"></a>P2P</h5></li>
</ol>
<p>&nbsp;&nbsp;P2P即点对点,它不同于广播式,P2P需要指定消息由谁接收,且只能由一个人接收.</p>
<ol>
<li><p>配置与广播式相同.</p>
</li>
<li><p>Controller</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * 通过SimpMessagingTemplate向浏览器发送消息.</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> SimpMessagingTemplate messagingTemplate;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment">  * Spring MVC可以直接在参数中注入principal对象,它包含当前用户的信息.</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> <span class="meta">@MessageMapping(&quot;/chat&quot;)</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handleChat</span><span class="params">(Principal principal, String msg)</span> </span>&#123;</span><br><span class="line">     <span class="comment">/**</span></span><br><span class="line"><span class="comment">      * 通过SimpMessagingTemplate.convertAndSendToUser向用户发送消息,</span></span><br><span class="line"><span class="comment">      * 第一个参数是接收者的用户,第二参数是浏览器订阅的地址,第三个参数是要发送的消息.</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line">     <span class="keyword">if</span> (principal.getName().equals(<span class="string">&quot;sun&quot;</span>)) &#123;</span><br><span class="line">         messagingTemplate.convertAndSendToUser(<span class="string">&quot;sylvanas&quot;</span>,</span><br><span class="line">                 <span class="string">&quot;/queue/notifications&quot;</span>, principal.getName() + <span class="string">&quot;-send:&quot;</span> + msg);</span><br><span class="line">     &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">         messagingTemplate.convertAndSendToUser(<span class="string">&quot;sun&quot;</span>,</span><br><span class="line">                 <span class="string">&quot;/queue/notifications&quot;</span>, principal.getName() + <span class="string">&quot;-send:&quot;</span> + msg);</span><br><span class="line">     &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure></li>
<li><p>js</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line">  &lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;!--suppress ALL --&gt;</span><br><span class="line">&lt;html xmlns=<span class="string">&quot;http://www.w3.org/1999/xhtml&quot;</span> xmlns:th=<span class="string">&quot;http://www.thymeleaf.org&quot;</span></span><br><span class="line">      xmlns:sec=<span class="string">&quot;http://www.thymeleaf.org/thymeleaf-extras-springsecurity3&quot;</span>&gt;</span><br><span class="line"></span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta content=<span class="string">&quot;text/html;charset=UTF-8&quot;</span>/&gt;</span><br><span class="line">    &lt;meta http-equiv=<span class="string">&quot;X-UA-Compatible&quot;</span> content=<span class="string">&quot;IE=edge&quot;</span>/&gt;</span><br><span class="line">    &lt;meta name=<span class="string">&quot;viewport&quot;</span> content=<span class="string">&quot;width=device-width,initial-scale=1&quot;</span>/&gt;</span><br><span class="line">    &lt;script th:src=<span class="string">&quot;@&#123;jquery-3.1.0.min.js&#125;&quot;</span>/&gt;</span><br><span class="line">    &lt;script th:src=<span class="string">&quot;@&#123;stomp.min.js&#125;&quot;</span>/&gt;</span><br><span class="line">    &lt;script th:src=<span class="string">&quot;@&#123;sockjs-1.0.0.min.js&#125;&quot;</span>/&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">&lt;p&gt;</span><br><span class="line">    聊天室</span><br><span class="line">&lt;/p&gt;</span><br><span class="line"></span><br><span class="line">&lt;form id=<span class="string">&quot;chatForm&quot;</span>&gt;</span><br><span class="line">    &lt;textarea rows=<span class="string">&quot;4&quot;</span> cols=<span class="string">&quot;60&quot;</span> name=<span class="string">&quot;text&quot;</span>&gt;&lt;/textarea&gt;</span><br><span class="line">    &lt;input type=<span class="string">&quot;submit&quot;</span>/&gt;</span><br><span class="line">&lt;/form&gt;</span><br><span class="line"></span><br><span class="line">&lt;script th:inline=<span class="string">&quot;javascript&quot;</span>&gt;</span><br><span class="line">    $(<span class="string">&#x27;#chatForm&#x27;</span>).submit(<span class="function"><span class="keyword">function</span>(<span class="params">e</span>)</span>&#123;</span><br><span class="line">        e.preventDefault();</span><br><span class="line">        <span class="keyword">var</span> text = $(<span class="string">&#x27;#chatForm&#x27;</span>).find(<span class="string">&#x27;textarea[name=&quot;text&quot;]&#x27;</span>).val();</span><br><span class="line">        sendSpittle(text);</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> socket = <span class="keyword">new</span> SockJS(<span class="string">&quot;/endpointChat&quot;</span>);</span><br><span class="line">    <span class="keyword">var</span> stomp = Stomp.over(socket);</span><br><span class="line">    stomp.connect(<span class="string">&#x27;guest&#x27;</span>,<span class="string">&#x27;guest&#x27;</span>,<span class="function"><span class="keyword">function</span>(<span class="params">frame</span>)</span>&#123;</span><br><span class="line">        <span class="comment">// 与messagingTemplate.convertAndSendToUser中定义的订阅地址保持一致</span></span><br><span class="line">        <span class="comment">// 但前面要多出一个/user,这个/user是必须的,只有使用了/user才会发送消息到指定的用户.</span></span><br><span class="line">        stomp.subscribe(<span class="string">&quot;/user/queue/notifications&quot;</span>,handleNotification);</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">handleNotification</span>(<span class="params">message</span>)</span>&#123;</span><br><span class="line">        $(<span class="string">&quot;#output&quot;</span>).append(<span class="string">&quot;&lt;b&gt;Received: &quot;</span> + message.body + <span class="string">&quot;&lt;/b&gt;&lt;br/&gt;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">sendSpittle</span>(<span class="params">text</span>)</span>&#123;</span><br><span class="line">        stomp.send(<span class="string">&quot;/chat&quot;</span>,&#123;&#125;,text);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    $(<span class="string">&#x27;#stop&#x27;</span>).click(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;socket.close()&#125;);</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;div id=<span class="string">&quot;output&quot;</span>&gt;&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">&lt;/body&gt;</span><br><span class="line"></span><br><span class="line">&lt;/html&gt; </span><br></pre></td></tr></table></figure>
<h3 id="异步消息队列"><a href="#异步消息队列" class="headerlink" title="异步消息队列"></a>异步消息队列</h3></li>
</ol>
<hr>
<p>&nbsp;&nbsp;异步消息队列主要用于各系统之间的通信与解耦,异步消息即为发送者无需关心消息接收者的处理和返回.</p>
<p>&nbsp;&nbsp;异步消息的主要概念为消息代理(message broker)和目的地(destination).消息是由消息代理负责接管并传递到指定目的地的.</p>
<p>&nbsp;&nbsp;目的地主要有2种:</p>
<ol>
<li>queue:用于P2P(point-to-point)的消息通信.</li>
<li>topic:用于发布/订阅(publish/subscribe)的消息通信.</li>
</ol>
<h4 id="Spring-Boot支持-1"><a href="#Spring-Boot支持-1" class="headerlink" title="Spring Boot支持"></a>Spring Boot支持</h4><hr>
<p>&nbsp;&nbsp;Spring对JMS和AMQP的支持来自于spring-jms、spring-rabbit.它们分别需要ConnectionFactory的实现来连接消息代理.并且提供了JmsTemplate和RabbitTemplate.</p>
<ul>
<li>JMS(Java Message Service)Java消息服务,它是基于JVM消息代理的规范.</li>
<li>AMQP(Advanced Message Queuing Protocol)高级消息队列协议,它不仅支持JVM,还支持跨语言和平台.AMQP的主要实现有RabbitMQ.</li>
</ul>
<p>&nbsp;&nbsp;Spring Boot对JMS支持的实有ActiveMQ,HornetQ,Artemis.以ActiveMQ为例:</p>
<ul>
<li>Spring Boot自动配置了ActiveMQConnectionFactory与JmsTemplate.</li>
<li>通过<code>spring.activemq</code>为前缀的属性来配置ActiveMQ相关的属性.</li>
<li>Spring Boot还自动开启了<code>@EnableJms</code>,即使用注解式消息监听的支持.</li>
</ul>
<p>&nbsp;&nbsp;Spring Boot对AMQP的实现RabbitMQ自动配置了如下内容:</p>
<ul>
<li>自动配置了ConnectionFactory和RabbitTemplate.</li>
<li>通过<code>spring.rabbitmq</code>为前缀的属性来配置RabbitMQ相关的属性.</li>
<li>自动开启了<code>@EnableRabbit</code>,即使用注解式消息监听的支持.</li>
</ul>
<h4 id="JMS-Example"><a href="#JMS-Example" class="headerlink" title="JMS Example"></a>JMS Example</h4><hr>
<p>&nbsp;&nbsp;添加依赖</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">      &lt;dependency&gt;</span><br><span class="line">	&lt;groupId&gt;org.springframework.boot&lt;&#x2F;groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;spring-boot-starter&lt;&#x2F;artifactId&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">	&lt;groupId&gt;org.springframework&lt;&#x2F;groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;spring-jms&lt;&#x2F;artifactId&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">	&lt;groupId&gt;org.apache.activemq&lt;&#x2F;groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;activemq-client&lt;&#x2F;artifactId&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br><span class="line"></span><br><span class="line">&lt;!-- 嵌入ActiveMQ --&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">	&lt;groupId&gt;org.apache.activemq&lt;&#x2F;groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;activemq-broker&lt;&#x2F;artifactId&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br><span class="line"></span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">	&lt;groupId&gt;org.springframework.boot&lt;&#x2F;groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;spring-boot-starter-test&lt;&#x2F;artifactId&gt;</span><br><span class="line">	&lt;scope&gt;test&lt;&#x2F;scope&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;在application.properties中配置activemq的地址.</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">spring.activemq.broker-url&#x3D;tcp:&#x2F;&#x2F;192.168.145.152:61616</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;定义JMS发送的消息需要实现MessageCreator接口.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Msg</span> <span class="keyword">implements</span> <span class="title">MessageCreator</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 重写createMessage方法.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Message <span class="title">createMessage</span><span class="params">(Session session)</span> <span class="keyword">throws</span> JMSException </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> session.createTextMessage(<span class="string">&quot;Hello World&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;发送消息,定义目的地.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Spring Boot提供了一个CommandLineRunner接口,用于程序启动后执行的代码</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@SuppressWarnings(&quot;SpringJavaAutowiringInspection&quot;)</span></span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringBootActivemqApplication</span> <span class="keyword">implements</span> <span class="title">CommandLineRunner</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SpringApplication.run(SpringBootActivemqApplication.class, args);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Autowired</span></span><br><span class="line">	<span class="keyword">private</span> JmsTemplate jmsTemplate;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">(String... strings)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">		<span class="comment">// 向目的地my-destination发送消息</span></span><br><span class="line">		jmsTemplate.send(<span class="string">&quot;my-destination&quot;</span>,<span class="keyword">new</span> Msg());</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;接收消息</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Receiver</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@JmsListener</span>是Spring 4.1提供的一个新特性,用来简化JMS开发.</span></span><br><span class="line"><span class="comment">     * destination指定要监听的目的地.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@JmsListener(destination = &quot;my-destination&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">receiveMessage</span><span class="params">(String message)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;接收到: &lt;&quot;</span> + message + <span class="string">&quot;&gt;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="AMQP-Example"><a href="#AMQP-Example" class="headerlink" title="AMQP Example"></a>AMQP Example</h4><hr>
<p>&nbsp;&nbsp;Spring Boot默认Rabbit主机位localhost,端口号为5672.</p>
<p>&nbsp;&nbsp;添加以下依赖:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">      &lt;dependency&gt;</span><br><span class="line">	&lt;groupId&gt;org.springframework.boot&lt;&#x2F;groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;spring-boot-starter-amqp&lt;&#x2F;artifactId&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">	&lt;groupId&gt;org.springframework.boot&lt;&#x2F;groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;spring-boot-starter-test&lt;&#x2F;artifactId&gt;</span><br><span class="line">	&lt;scope&gt;test&lt;&#x2F;scope&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;在application.properties中配置RabbitMQ的地址.</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">spring.rabbitmq.host&#x3D;192.168.145.152</span><br><span class="line">spring.rabbitmq.port&#x3D;5672</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;发送消息,定义目的地.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SuppressWarnings(&quot;SpringJavaAutowiringInspection&quot;)</span></span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringBootRabbitmqApplication</span> <span class="keyword">implements</span> <span class="title">CommandLineRunner</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SpringApplication.run(SpringBootRabbitmqApplication.class, args);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Autowired</span></span><br><span class="line">	<span class="keyword">private</span> RabbitTemplate rabbitTemplate;</span><br><span class="line"></span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	 * 定义目的地</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">	<span class="meta">@Bean</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> Queue <span class="title">myQueue</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">new</span> Queue(<span class="string">&quot;my-queue&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	 * 使用rabbitTemplate的convertAndSend方法向队列my-queue发送消息.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">(String... strings)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">		rabbitTemplate.convertAndSend(<span class="string">&quot;my-queue&quot;</span>,<span class="string">&quot;Hello RabbitMQ!&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>&nbsp;&nbsp;接收消息</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Receiver</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@RabbitListener(queues = &quot;my-queue&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">receiveMessage</span><span class="params">(String message)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Received &lt;&quot;</span> + message + <span class="string">&quot;&gt;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="end"><a href="#end" class="headerlink" title="end"></a>end</h3><blockquote>
<p>资料参考于 JavaEE开发的颠覆者: Spring Boot实战</p>
</blockquote>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/yuwanzi.io/tags/Java/" rel="tag"># Java</a>
              <a href="/yuwanzi.io/tags/Spring/" rel="tag"># Spring</a>
              <a href="/yuwanzi.io/tags/Spring-Boot/" rel="tag"># Spring Boot</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/yuwanzi.io/2016/08/02/2016-08-2-Spring-security/" rel="prev" title="Spring Security安全控制">
                  <i class="fa fa-chevron-left"></i> Spring Security安全控制
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/yuwanzi.io/2016/08/04/2016-08-4-Spring-batch/" rel="next" title="Spring Batch数据批处理">
                  Spring Batch数据批处理 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>







<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      const activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      const commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>
</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">玉丸子</span>
</div>
  <div class="powered-by">Erstellt mit  <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a>
  </div>

    </div>
  </footer>

  
  <script src="//cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js"></script>
<script src="/yuwanzi.io/js/utils.js"></script><script src="/yuwanzi.io/js/motion.js"></script><script src="/yuwanzi.io/js/schemes/muse.js"></script><script src="/yuwanzi.io/js/next-boot.js"></script>

  






  





</body>
</html>
